
#include <BRender>
#include <BPainter>
#include <BScene>
#include <BShape>
#include <BViewer>
#include <BPicker>
#include <BMouseEvent>
#include <BKeyEvent>

#include "TargetHandler.h"

TargetHandler::TargetHandler()
{
	_transStep = 0;
}
TargetHandler::~TargetHandler()
{

}

void TargetHandler::render(BRender& render)
{
	render.setLighting(false);
	render.setLineSmooth(true);
	render.setLineWidth(3);
	if (_targetNode)
	{
		render.setColor(255, 255, 255);
		render.drawSpace(_targetNode->space());
		if (_targetShape)
		{
			BBox box = _targetShape->box() * _targetShape->matrix() * _targetNode->matrix();
			render.setColor(100, 255, 100);
			render.drawBox(box);
		}
	}
	else
	{
		if (_targetShape)
		{
			BBox box = _targetShape->box() * _targetShape->matrix();
			render.setColor(100, 255, 100);
			render.drawBox(box);
		}
	}

	render.setLineWidth(1);
	if (_hoveredNode)
	{
		render.setColor(255, 255, 255);
		render.drawSpace(_hoveredNode->space());
		if (_hoveredShape)
		{
			BBox box = _hoveredShape->box() * _hoveredShape->matrix() * _hoveredNode->matrix();
			render.setColor(100, 255, 100);
			render.drawBox(box);
		}
	}
	else
	{
		if (_hoveredShape)
		{
			BBox box = _hoveredShape->box() * _hoveredShape->matrix();
			render.setColor(100, 255, 100);
			render.drawBox(box);
		}
	}

	BQuad quad;
	quad.a().set(0, -100, 0);
	quad.b().set(0, -100, 50);
	quad.c().set(80, -100, 50);
	quad.d().set(80, -100, 0);
	render.bind(this->camera());
	render.fillQuad(quad);
	render.unbind();

}

void TargetHandler::updateEvent(const BEvent& event)
{
	if (_transStep > 0)
	{
		BVector center = this->camera()->center();
		BVector destination = center;
		if (_targetShape)
			destination = _targetShape->space().center();
		if (_targetNode)
			destination = _targetNode->space().center();
		this->camera()->setCenter(center + (destination - center) / _transStep);
		_transStep--;
		if (_transStep == 0)
		{
			this->camera()->setCenter(destination);
		}
	}
}

void TargetHandler::keyReleaseEvent(const BKeyEvent& keyEvent)
{
	Key key = keyEvent.key();
	if (key == Key_Space)
	{
		if (_targetShape)
		{
			this->focus(_targetShape);
		}
		keyEvent.accept();
	}
	if (key == Key_W)
	{
		if (_targetShape)
		{
			_targetShape->setPolyMode(Poly_Line);
		}
		keyEvent.accept();
	}
	if (key == Key_F)
	{
		if (_targetShape)
		{
			_targetShape->setPolyMode(Poly_Fill);
		}
		keyEvent.accept();
	}
	if (key == Key_P)
	{
		if (_targetShape)
		{
			_targetShape->setPolyMode(Poly_Point);
		}
		keyEvent.accept();
	}
	if (key == Key_L)
	{
		if (_targetShape)
		{
			bool lighting = !_targetShape->lighting();
			_targetShape->setLighting(lighting);
		}
		keyEvent.accept();
	}
}

void TargetHandler::mouseMoveEvent(const BMouseEvent& mouseEvent)
{
	if (mouseEvent.button() == Button_None)
	{
		const BPoint& pos = mouseEvent.pos();
		BLine line = this->viewer()->line(pos);
		emit("line-changed", line);
		BPicker picker(line);
		BNode* hoveredNode = 0;
		BShape* hoveredShape = 0;
		if (const BPickHit* hit = this->viewer()->pick(pos))
		{
			hoveredNode = hit->node();
			hoveredShape = hit->shape();
		}
		if (_hoveredNode != hoveredNode || _hoveredShape != hoveredShape)
		{
			_hoveredNode = hoveredNode;
			_hoveredShape = hoveredShape;
			this->fresh();
		}
	}
	return BRoundHandler::mouseMoveEvent(mouseEvent);
}

void TargetHandler::mouseClickEvent(const BMouseEvent& mouseEvent)
{
	if (mouseEvent.button() == Button_Left)
	{
		const BPoint& pos = mouseEvent.pos();
		BLine line = this->viewer()->line(pos);
		BPicker picker(line);
		BNode* targetNode = 0;
		BShape* targetShape = 0;
		if (const BPickHit* hit = picker.apply(this->scene()))
		{
			targetNode = hit->node();
			targetShape = hit->shape();
		}
		if (_targetNode != targetNode || _targetShape != targetShape)
		{
			_targetNode = targetNode;
			_targetShape = targetShape;
			_transStep = 10;
			emit("target-changed", _targetShape);
			this->fresh();
		}
	}
	mouseEvent.accept();
}
